﻿Imports System.Runtime.CompilerServices
Imports System.Globalization

'created by : Sum
'created date : 18/1/2011
'decription : this extenstion is for datetime
Namespace extension
    Public Module DateTimeExtension
        <Extension()> _
        Public Function AddWeekdays(ByVal [date] As DateTime, ByVal days As Integer) As DateTime
            Dim sign = If(days < 0, -1, 1)
            Dim unsignedDays = Math.Abs(days)
            Dim weekdaysAdded = 0
            While weekdaysAdded < unsignedDays
                [date] = [date].AddDays(sign)
                If [date].DayOfWeek <> DayOfWeek.Saturday AndAlso [date].DayOfWeek <> DayOfWeek.Sunday Then
                    weekdaysAdded += 1
                End If
            End While
            Return [date]
        End Function

        'created date: 16/2/2012
        'created by:sum
        <Extension()> _
        Public Function FindNextDayofWeek(ByVal [date] As DateTime, ByVal dof As DayOfWeek) As DateTime

            While [date].DayOfWeek <> dof
                If [date].DayOfWeek = dof Then
                    Exit While
                Else
                    [date] = [date].AddDays(1)
                End If
            End While

            Return [date]
        End Function


        <Extension()> _
        Public Function SetTime(ByVal [date] As DateTime, ByVal hour As Integer) As DateTime
            Return [date].SetTime(hour, 0, 0, 0)
        End Function
        <Extension()> _
        Public Function SetTime(ByVal [date] As DateTime, ByVal hour As Integer, ByVal minute As Integer) As DateTime
            Return [date].SetTime(hour, minute, 0, 0)
        End Function
        <Extension()> _
        Public Function SetTime(ByVal [date] As DateTime, ByVal hour As Integer, ByVal minute As Integer, ByVal second As Integer) As DateTime
            Return [date].SetTime(hour, minute, second, 0)
        End Function
        <Extension()> _
        Public Function SetTime(ByVal [date] As DateTime, ByVal hour As Integer, ByVal minute As Integer, ByVal second As Integer, ByVal millisecond As Integer) As DateTime
            Return New DateTime([date].Year, [date].Month, [date].Day, hour, minute, second, _
             millisecond)
        End Function

        <Extension()> _
        Public Function FirstDayOfMonth(ByVal [date] As DateTime) As DateTime
            Return New DateTime([date].Year, [date].Month, 1)
        End Function
        <Extension()> _
        Public Function LastDayOfMonth(ByVal [date] As DateTime) As DateTime
            Return New DateTime([date].Year, [date].Month, DateTime.DaysInMonth([date].Year, [date].Month))
        End Function

        <Extension()> _
        Public Function ToString(ByVal [date] As System.Nullable(Of DateTime)) As String
            Return [date].ToString(Nothing, DateTimeFormatInfo.CurrentInfo)
        End Function
        <Extension()> _
        Public Function ToString(ByVal [date] As System.Nullable(Of DateTime), ByVal format As String) As String
            Return [date].ToString(format, DateTimeFormatInfo.CurrentInfo)
        End Function
        <Extension()> _
        Public Function ToString(ByVal [date] As System.Nullable(Of DateTime), ByVal provider As IFormatProvider) As String
            Return [date].ToString(Nothing, provider)
        End Function
        <Extension()> _
        Public Function ToString(ByVal [date] As System.Nullable(Of DateTime), ByVal format As String, ByVal provider As IFormatProvider) As String
            If [date].HasValue Then
                Return [date].Value.ToString(format, provider)
            Else
                Return String.Empty
            End If
        End Function

        <Extension()> _
        Public Function ToRelativeDateString(ByVal [date] As DateTime) As String
            Return GetRelativeDateValue([date], DateTime.Now)
        End Function
        <Extension()> _
        Public Function ToRelativeDateStringUtc(ByVal [date] As DateTime) As String
            Return GetRelativeDateValue([date], DateTime.UtcNow)
        End Function
        <Extension()> _
        Private Function GetRelativeDateValue(ByVal [date] As DateTime, ByVal comparedTo As DateTime) As String
            Dim diff As TimeSpan = comparedTo.Subtract([date])
            If diff.TotalDays >= 365 Then
                Return String.Concat("on ", [date].ToString("MMMM d, yyyy"))
            End If
            If diff.TotalDays >= 7 Then
                Return String.Concat("on ", [date].ToString("MMMM d"))
            ElseIf diff.TotalDays > 1 Then
                Return String.Format("{0:N0} days ago", diff.TotalDays)
            ElseIf diff.TotalDays = 1 Then
                Return "yesterday"
            ElseIf diff.TotalHours >= 2 Then
                Return String.Format("{0:N0} hours ago", diff.TotalHours)
            ElseIf diff.TotalMinutes >= 60 Then
                Return "more than an hour ago"
            ElseIf diff.TotalMinutes >= 5 Then
                Return String.Format("{0:N0} minutes ago", diff.TotalMinutes)
            End If
            If diff.TotalMinutes >= 1 Then
                Return "a few minutes ago"
            Else
                Return "less than a minute ago"
            End If
        End Function

    End Module
End Namespace

